home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / manage / snmp / mit / bsd / udps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-17  |  10.4 KB  |  494 lines

  1.  
  2. /*
  3.  *    $Header: udps.c,v 3.0 91/05/17 16:14:10 jrd Rel $
  4.  *    Author: J. Davin
  5.  *    Copyright 1988, 1989, Massachusetts Institute of Technology
  6.  *    See permission and disclaimer notice in file "notice.h"
  7.  */
  8.  
  9. #include    <notice.h>
  10.  
  11. #include    <sys/types.h>
  12. #include    <nlist.h>
  13. #include    <sys/mbuf.h>
  14. #include    <sys/socket.h>
  15. #include    <netinet/in.h>
  16. #include    <net/route.h>
  17. #include    <netinet/in_pcb.h>
  18. #include    <netinet/ip_var.h>
  19. #include    <netinet/udp.h>
  20. #include    <netinet/udp_var.h>
  21.  
  22. #include    <ctypes.h>
  23. #include    <error.h>
  24. #include    <debug.h>
  25. #include    <local.h>
  26. #include    <mix.h>
  27. #include    <mis.h>
  28. #include    <miv.h>
  29. #include    <avl.h>
  30. #include    <asn.h>
  31.  
  32. #include    <kmem.h>
  33. #include    <udps.h>
  34.  
  35. #define        udpsMaxNameSize        (16)
  36.  
  37. typedef        struct            UdpsRecTag {
  38.  
  39.         CUnslType        udpsRecAddr;
  40.         CByteType        udpsRecName [ udpsMaxNameSize ];
  41.         CIntfType        udpsRecNameLen;
  42.         CUnslType        udpsRecLAddr;
  43.         CUnslType        udpsRecFAddr;
  44.         CUnssType        udpsRecFPort;
  45.         CUnssType        udpsRecLPort;
  46.  
  47.         }            UdpsRecType;
  48.  
  49. typedef        UdpsRecType        *UdpsRecPtrType;
  50.  
  51. static    AvlIdType    udpsTree;
  52.  
  53. static    CUnslType        udpsHead;
  54. static    CUnslType        udpsZero;
  55.  
  56. static    CIntfType    udpsDstToName (oid, n, dst)
  57.  
  58. CBytePtrType        oid;
  59. CIntfType        n;
  60. AvlInfoType        dst;
  61.  
  62. {
  63.     CBytePtrType            bp;
  64.     CIntfType            k;
  65.     CIntfType            i;
  66.     CIntfType            c;
  67.     CUnssType            d;
  68.  
  69.     bp = (CBytePtrType) & ((UdpsRecPtrType) dst)->udpsRecLAddr;
  70.     k = (CIntfType) 0;
  71.     for (i = sizeof (CUnslType); (k < n) && (i != 0); i--) {
  72.         if ((*bp & (CByteType) 0x80) != (CByteType) 0) {
  73.             *oid++ = (CByteType) 129;
  74.             k++;
  75.         }
  76.         *oid++ = (*bp++ & (CByteType) 0x7F);
  77.         k++;
  78.     }
  79.     d = ((UdpsRecPtrType) dst)->udpsRecLPort;
  80.     if ((c = ((d >> 14) & 0x03)) != (CIntfType) 0) {
  81.         *oid++ = c | 0x80;
  82.         k++;
  83.     }
  84.     if ((c = (d >> 7)) != (CUnssType) 0) {
  85.         *oid++ = (c & 0x7F) | 0x80;
  86.         k++;
  87.     }
  88.     *oid++ = (d & 0x7F);
  89.     k++;
  90.  
  91.     return ((k < n) ? k : (CIntfType) -1);
  92. }
  93.  
  94. static    AvlBalanceType    udpsCmpFn (info, name, namelen)
  95.  
  96. AvlInfoType        info;
  97. AvlNamePtrType        name;
  98. AvlLengthType        namelen;
  99.  
  100. {
  101.         CUnsfType               n;
  102.         CBytePtrType        cp;
  103.         CIntfType               r;
  104.  
  105.     n = (CUnsfType) ((UdpsRecPtrType) info)->udpsRecNameLen;
  106.     cp = ((UdpsRecPtrType) info)->udpsRecName;
  107.         r = (CIntfType) 0;
  108.         if (namelen >= n) {
  109.                 while ((n-- != 0) && ((r = (CIntfType) *name++ -
  110.                         (CIntfType) *cp++) == 0));
  111.         }
  112.         else {
  113.                 while ((namelen-- != 0) && ((r = (CIntfType) *name++ -
  114.                         (CIntfType) *cp++) == 0));
  115.                 if (r == 0) {
  116.                         r = -1;
  117.                 }
  118.         }
  119.  
  120.         if (r == 0) {
  121.                 return (avlDirBalanced);
  122.         }
  123.         else if (r < 0) {
  124.                 return (avlDirLeft);
  125.         }
  126.         else {
  127.                 return (avlDirRight);
  128.         }
  129. }
  130.  
  131. static    AsnIdType    udpsRetrieve (mix, info)
  132.  
  133. MixCookieType        mix;
  134. AvlInfoType        info;
  135.  
  136. {
  137.     AsnIdType        result;
  138.  
  139.     switch ((int) mix) {
  140.  
  141.     case 0:
  142.         result = asnOctetString (asnClassApplication,
  143.              (AsnTagType) 0,
  144.              (CBytePtrType) & ((UdpsRecPtrType) info)->udpsRecLAddr,
  145.              (AsnLengthType) 4);
  146.         break;
  147.  
  148.     case 1:
  149.         result = asnUnsl (asnClassUniversal, (AsnTagType) 2,
  150.                 (CUnslType) ((UdpsRecPtrType) info)->udpsRecLPort);
  151.         break;
  152.  
  153.     default:
  154.         result = (AsnIdType) 0;
  155.         break;
  156.     }
  157.     return (result);
  158. }
  159.  
  160. static    CUnslType    udpsRefreshEntry (last, location)
  161.  
  162. CUnslType        last;
  163. CUnslType        location;
  164.  
  165. {
  166.     struct        inpcb    inpcbBuf;
  167.     struct        inpcb    *rp;
  168.     AvlInfoType        info;
  169.     UdpsRecPtrType        ri;
  170.     UdpsRecType        rb;
  171.  
  172.     if (kmemRead ((CBytePtrType) & inpcbBuf, (CIntfType) sizeof (inpcbBuf),
  173.         location) != (CIntfType) sizeof (inpcbBuf)) {
  174.         return ((CUnslType) 0);
  175.     }
  176.  
  177.     /*
  178.      *    Did things change under us since our last dip
  179.      *    into the kernel?
  180.      */
  181.  
  182.     if (inpcbBuf.inp_prev != (struct inpcb *) last) {
  183.         return ((CUnslType) 0);
  184.     }
  185.  
  186.     rp = & inpcbBuf;
  187.     DEBUG0 ("udpsRefreshEntry:\n");
  188.     DEBUG1 ("INPCB at %X\n", location);
  189.     DEBUG1 ("INPCB.inp_prev:    %X\n", rp->inp_prev);
  190.     DEBUG1 ("INPCB.inp_next:    %X\n", rp->inp_next);
  191.     DEBUG1 ("INPCB.inp_laddr:    %X\n", rp->inp_laddr);
  192.     DEBUG1 ("INPCB.inp_faddr:    %X\n", rp->inp_faddr);
  193.     DEBUG1 ("INPCB.inp_lport:    %d\n", rp->inp_lport);
  194.     DEBUG1 ("INPCB.inp_fport:    %d\n", rp->inp_fport);
  195.     DEBUG1 ("INPCB.inp_ppcb:    %X\n", rp->inp_ppcb);
  196.     DEBUG1 ("INPCB.inp_socket:    %X\n", rp->inp_socket);
  197.  
  198.     rb.udpsRecLAddr = (CUnslType) rp->inp_laddr.s_addr;
  199.     rb.udpsRecLPort = (CUnssType) ntohs (rp->inp_lport);
  200.     rb.udpsRecFAddr = (CUnslType) rp->inp_faddr.s_addr;
  201.     rb.udpsRecFPort = (CUnssType) ntohs (rp->inp_fport);
  202.     rb.udpsRecNameLen = udpsDstToName (rb.udpsRecName,
  203.         (CIntfType) sizeof (rb.udpsRecName),
  204.                 (AvlInfoType) & rb);                       
  205.     rb.udpsRecAddr = location;
  206.  
  207.     info = avlFind (udpsTree, (AvlNamePtrType) rb.udpsRecName,
  208.         (AvlLengthType) rb.udpsRecNameLen);
  209.     if (info != (AvlInfoType) 0) {
  210.         ((UdpsRecPtrType) info)->udpsRecAddr = location;
  211.         return ((CUnslType) inpcbBuf.inp_next);
  212.     }
  213.  
  214.     ri = (UdpsRecPtrType) malloc ((unsigned) sizeof (*ri));
  215.     if (ri != (UdpsRecPtrType) 0) {
  216.         *ri = rb;
  217.         (void) avlInsert (udpsTree, (AvlNamePtrType) rb.udpsRecName,
  218.             (AvlLengthType) rb.udpsRecNameLen, (AvlInfoType) ri);
  219.     }
  220.  
  221.     return ((CUnslType) rp->inp_next);
  222. }
  223.  
  224. static    CVoidType    udpsRefreshChain (location)
  225.  
  226. CUnslType        location;
  227.  
  228. {
  229.     CUnsfType            i;
  230.     CUnslType            head;
  231.     CUnslType            prev;
  232.     CUnslType            next;
  233.  
  234.     if (kmemRead ((CBytePtrType) & head,
  235.         (CIntfType) sizeof (head), location) ==
  236.             (CIntfType) sizeof (head)) {
  237.         prev = location;
  238.         while ((head != (CUnslType) 0) &&
  239.                 (head != location)) {
  240.                 next = udpsRefreshEntry (prev, head);
  241.             prev = head;
  242.             head = next;
  243.         }
  244.     }
  245. }
  246.  
  247. static    AvlIdType    udpsFreeChain (tree)
  248.  
  249. AvlIdType        tree;
  250.  
  251. {
  252.     AvlInfoType        info;
  253.     CByteType        name [ udpsMaxNameSize ];
  254.     AvlLengthType        namelen;
  255.  
  256.     namelen = (AvlLengthType) 0;
  257.     while ((info = avlCessor (tree, (AvlNamePtrType) name,
  258.         namelen)) != (AvlInfoType) 0) {
  259.         namelen = ((UdpsRecPtrType) info)->udpsRecNameLen;
  260.         bcopy ((char *) ((UdpsRecPtrType) info)->udpsRecName,
  261.                (char *) name, (int) namelen);
  262.         (void) free ((char *) info);
  263.     }
  264.     return (avlFree (tree));
  265. }
  266.  
  267. static    CVoidType    udpsRefresh ()
  268.  
  269. {
  270.     udpsTree = udpsFreeChain (udpsTree);
  271.     udpsTree = avlNew (udpsCmpFn, (AvlPrintFnType) 0);
  272.     udpsRefreshChain (udpsHead);
  273. }
  274.  
  275. static    MixStatusType    udpsRelease (cookie)
  276.  
  277. MixCookieType        cookie;
  278.  
  279. {
  280.     cookie = cookie;
  281.     return (smpErrorGeneric);
  282. }
  283.  
  284. static    MixStatusType    udpsCreate (cookie, name, namelen, asn)
  285.  
  286. MixCookieType        cookie;
  287. MixNamePtrType        name;
  288. MixLengthType        namelen;
  289. AsnIdType        asn;
  290.  
  291. {
  292.     cookie = cookie;
  293.     name = name;
  294.     namelen = namelen;
  295.     asn = asn;
  296.     return (smpErrorGeneric);
  297. }
  298.  
  299. static    MixStatusType    udpsDestroy (cookie, name, namelen)
  300.  
  301. MixCookieType        cookie;
  302. MixNamePtrType        name;
  303. MixLengthType        namelen;
  304.  
  305. {
  306.     cookie = cookie;
  307.     name = name;
  308.     namelen = namelen;
  309.     return (smpErrorGeneric);
  310. }
  311.  
  312. static    AsnIdType    udpsGet (cookie, name, namelen)
  313.  
  314. MixCookieType        cookie;
  315. MixNamePtrType        name;
  316. MixLengthType        namelen;
  317.  
  318. {
  319.     AvlInfoType        info;
  320.  
  321.     udpsRefresh ();
  322.     info = avlFind (udpsTree, (AvlNamePtrType) name,
  323.         (AvlLengthType) namelen);
  324.     if (info == (AvlInfoType) 0) {
  325.         return ((AsnIdType) 0);
  326.     }
  327.     else {
  328.         return (udpsRetrieve (cookie, info));
  329.     }
  330. }
  331.  
  332. static    MixStatusType    udpsSet (cookie, name, namelen, asn)
  333.  
  334. MixCookieType        cookie;
  335. MixNamePtrType        name;
  336. MixLengthType        namelen;
  337. AsnIdType        asn;
  338.  
  339. {
  340.     cookie = cookie;
  341.     name = name;
  342.     namelen = namelen;
  343.     asn = asn;
  344.     return (smpErrorGeneric);
  345. }
  346.  
  347. static    AsnIdType    udpsNext (cookie, name, namelenp)
  348.  
  349. MixCookieType        cookie;
  350. MixNamePtrType        name;
  351. MixLengthPtrType    namelenp;
  352.  
  353. {
  354.     AvlInfoType        info;
  355.     AsnIdType        result;
  356.  
  357.     udpsRefresh ();
  358.     do {
  359.  
  360.         info = avlCessor (udpsTree, (AvlNamePtrType) name,
  361.             (AvlLengthType) *namelenp);
  362.         if (info != (AvlInfoType) 0) {
  363.             (void) bcopy ((char *)
  364.             ((UdpsRecPtrType) info)->udpsRecName, (char *) name,
  365.             (int) ((UdpsRecPtrType) info)->udpsRecNameLen);
  366.             *namelenp = (MixLengthType)
  367.                 ((UdpsRecPtrType) info)->udpsRecNameLen;
  368.             result = udpsRetrieve (cookie, info);
  369.         }
  370.         else {
  371.             result = (AsnIdType) 0;
  372.         }
  373.  
  374.     } while ((info != (AvlInfoType) 0) && (result == (AsnIdType) 0));
  375.  
  376.     return (result);
  377. }
  378.  
  379. static    AsnIdType    udpsStatGet (cookie, name, namelen)
  380.  
  381. MixCookieType        cookie;
  382. MixNamePtrType        name;
  383. MixLengthType        namelen;
  384.  
  385. {
  386.     AsnIdType            result;
  387.     struct    udpstat        stats;
  388.  
  389.     if (namelen != (MixLengthType) 1) {
  390.         result = (AsnIdType) 0;
  391.     }
  392.     else if (*name != (MixNameType) 0) {
  393.         result = (AsnIdType) 0;
  394.     }
  395.     else if (kmemRead ((CBytePtrType) & stats,
  396.         (CIntfType) sizeof (stats), (CUnslType) cookie) !=
  397.             (CIntfType) sizeof (stats)) {
  398.         result = (AsnIdType) 0;
  399.     }
  400.     else {
  401.         result = asnUnsl (asnClassApplication,
  402.                 (AsnTagType) 1,
  403.             (CUnslType) stats.udps_hdrops +
  404.             stats.udps_badlen + stats.udps_badsum);
  405.     }
  406.     return (result);
  407. }
  408.  
  409. static    AsnIdType    udpsStatNext (cookie, name, namelenp)
  410.  
  411. MixCookieType        cookie;
  412. MixNamePtrType        name;
  413. MixLengthPtrType    namelenp;
  414.  
  415. {
  416.     AsnIdType            result;
  417.     struct    udpstat        stats;
  418.  
  419.     if (*namelenp != (MixLengthType) 0) {
  420.         result = (AsnIdType) 0;
  421.     }
  422.     else if (kmemRead ((CBytePtrType) & stats,
  423.         (CIntfType) sizeof (stats), (CUnslType) cookie) !=
  424.             (CIntfType) sizeof (stats)) {
  425.         result = (AsnIdType) 0;
  426.     }
  427.     else {
  428.         result = asnUnsl (asnClassApplication,
  429.                 (AsnTagType) 1,
  430.             (CUnslType) stats.udps_hdrops +
  431.             stats.udps_badlen + stats.udps_badsum);
  432.         *namelenp = (MixLengthType) 1;
  433.         *name = (MixNameType) 0;
  434.     }
  435.     return (result);
  436. }
  437.  
  438. static    MixOpsType    udpsOps = {
  439.  
  440.             udpsRelease,
  441.             udpsCreate,
  442.             udpsDestroy,
  443.             udpsNext,
  444.             udpsGet,
  445.             udpsSet
  446.  
  447.             };
  448.  
  449. static    MixOpsType    udpsStatOps = {
  450.  
  451.             udpsRelease,
  452.             udpsCreate,
  453.             udpsDestroy,
  454.             udpsStatNext,
  455.             udpsStatGet,
  456.             udpsSet
  457.  
  458.             };
  459.  
  460. CVoidType        udpsInit ()
  461.  
  462. {
  463.     struct        nlist        nl [ 4 ];
  464.  
  465.     nl [ 0 ].n_name = "_udb";
  466.     nl [ 1 ].n_name = "_udpstat";
  467.     nl [ 2 ].n_name = (char *) 0;
  468.     if (nlist ("/vmunix", nl) != 0) {
  469.         return;
  470.     }
  471.     udpsHead = (CUnslType) nl [ 0 ].n_value;
  472.  
  473.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\7\5\1\1",
  474.         (MixLengthType) 9, & udpsOps, (MixCookieType) 0);
  475.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\7\5\1\2",
  476.         (MixLengthType) 9, & udpsOps, (MixCookieType) 1);
  477.     /*
  478.      *    When the kernel doesn't count it, export a zero
  479.      */
  480.     udpsZero =  (CUnslType) 0;
  481.     (void) mivCounterRO ((MixNamePtrType) "\53\6\1\2\1\7\1",
  482.         (MixLengthType) 7, & udpsZero);
  483.     (void) mivCounterRO ((MixNamePtrType) "\53\6\1\2\1\7\2",
  484.         (MixLengthType) 7, & udpsZero);
  485.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\7\3",
  486.         (MixLengthType) 7, & udpsStatOps,
  487.         (MixCookieType) nl [ 1 ].n_value);
  488.     (void) mivCounterRO ((MixNamePtrType) "\53\6\1\2\1\7\4",
  489.         (MixLengthType) 7, & udpsZero);
  490.  
  491.     udpsTree = avlNew (udpsCmpFn, (AvlPrintFnType) 0);
  492. }
  493.  
  494.